package com.youzhi.backend.util;

import cn.hutool.core.util.StrUtil;
import com.youzhi.backend.entity.Button;
import com.youzhi.backend.entity.Menu;
import com.youzhi.backend.entity.Privilege;
import com.youzhi.backend.entity.RolePrivilege;
import com.youzhi.backend.service.IButtonService;
import com.youzhi.backend.service.IMenuService;
import com.youzhi.backend.service.IPrivilegeService;
import com.youzhi.backend.service.IRolePrivilegeService;
import com.youzhi.backend.service.impl.MenuServiceImpl;
import com.youzhi.backend.service.impl.PrivilegeServiceImpl;
import com.youzhi.backend.service.impl.RolePrivilegeServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Date;

/**
 * 权限添加工具类
 */
public class PrivilegeInsertUtil {

    //类型: 1目录 2页面',
    public static int menu_type_dictionary = 1;

    public static int menu_type_page = 2;

    //1：页面权限（指这个页面用户是否可见）2：按钮权限（指页面上的按钮用户是否有可操作权限
    public static int privilege_type_page = 1;

    public static int privilege_type_button = 2;


    public static ApplicationContext applicationContext;

    static {
        //初始化spring上下文

        applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
    }


    /**
     * 插入菜单
     *
     * @param parentName    父菜单名称 不传则为一级菜单
     * @param menuName      菜单名称
     * @param menuType      菜单类型 页面或目录
     * @param privilegeCode 权限code 不传则给基本的home权限（home是最基本的权限进入主页的权限） ,默认与admin角色关联
     * @param url           权限url 可以不传
     */
    public static void insertMenu(String parentName, String menuName, int menuType, String privilegeCode, String url) {
        url = (url == null ? "/example" : url);
        privilegeCode = (privilegeCode == null ? "home" : privilegeCode);

        Menu menu = getMenuEntity(parentName, menuName, menuType, privilegeCode, url);

        getMenService().save(menu);

        if (StrUtil.isNotEmpty(privilegeCode)) {

            Privilege privilege = getPrivilege(menuName, privilege_type_page, privilegeCode, url);
            getPrivilegeService().save(privilege);

            //将新添加的权限默认与admin角色进行关联
            addRelationWithAdmin(privilege);

        }

    }


    /**
     * 插入按钮
     *
     * @param menuName      需要放置的菜单的名称
     * @param name          按钮的名称
     * @param url           按钮操作对应的后台url
     * @param privilegeCode 按钮权限code ,默认与admin角色关联
     */
    public static void insertButton(String menuName, String name, String privilegeCode, String url) {

        Button button = getButton(menuName, name, privilegeCode, url);
        getButtonService().save(button);

        Privilege privilege = getPrivilege(button.getName(), privilege_type_button, privilegeCode, url);
        getPrivilegeService().save(privilege);

        //将新添加的权限默认与admin角色进行关联
        addRelationWithAdmin(privilege);

    }

    private static Button getButton(String menuName, String name, String privilegeCode, String url) {

        Menu menu = getMenService().getByName(menuName);

        Button button = new Button();
        String buttonName = menuName + "|" + name;
        button.setName(buttonName);
        button.setMenuId(menu.getId());
        button.setPrivilegeCode(privilegeCode);
        button.setUrl(url);
        button.setUpdateTime(new Date());
        button.setCreateTime(new Date());

        return button;
    }


    private static void addRelationWithAdmin(Privilege privilege) {
        RolePrivilege rolePrivilege = new RolePrivilege();
        rolePrivilege.setRoleId(1L);
        rolePrivilege.setRoleCode("admin");
        rolePrivilege.setPrivilegeId(privilege.getId());
        rolePrivilege.setPrivilegeCode(privilege.getCode());
        rolePrivilege.setCreateTime(new Date());
        rolePrivilege.setUpdateTime(new Date());
        getRolePrivilegeService().save(rolePrivilege);
    }


    private static Privilege getPrivilege(String name, int type, String code, String url) {
        Privilege privilege = new Privilege();
        privilege.setName(name);
        privilege.setCode(code);
        privilege.setPrivilegeType(type);
        privilege.setUrl(url);
        privilege.setCreateTime(new Date());
        privilege.setUpdateTime(new Date());
        return privilege;
    }

    private static Menu getMenuEntity(String parentName, String menuName, int menuType, String privilegeCode, String url) {
        Menu parent = null;
        if (StrUtil.isNotEmpty(parentName)) {
            parent = getParentMenu(parentName);
        }

        Menu menu = new Menu();
        if (parent != null) {
            menu.setParentId(parent.getId());
        } else {
            menu.setParentId(0L);
        }
        menu.setName(menuName);
        //如果权限code设置为空给一个最基本的权限
        menu.setPrivilegeCode(privilegeCode);
        menu.setType(menuType);
        menu.setUrl(url);
        menu.setCreateTime(new Date());
        menu.setUpdateTime(new Date());
        return menu;
    }


    private static Menu getParentMenu(String parentName) {
        IMenuService menService = getMenService();
        Menu menu = menService.getByName(parentName);
        if (menu == null) {
            throw new RuntimeException("父级菜单不存在");
        }
        return menu;
    }


    public static IMenuService getMenService() {
        return applicationContext.getBean(MenuServiceImpl.class);
    }


    public static IPrivilegeService getPrivilegeService() {
        return applicationContext.getBean(PrivilegeServiceImpl.class);
    }


    public static IRolePrivilegeService getRolePrivilegeService() {
        return applicationContext.getBean(RolePrivilegeServiceImpl.class);
    }


    public static IButtonService getButtonService() {
        return applicationContext.getBean(IButtonService.class);
    }

    public static void main(String[] args) {

        /**
         * 插入菜单
         * @param parentName    父菜单名称 不传则为一级菜单
         * @param menuName      菜单名称
         * @param menuType      菜单类型 页面或目录
         * @param privilegeCode 权限code 不传则给基本的home权限（home是最基本的权限进入主页的权限） ,默认与admin角色关联
         * @param url           权限url 可以不传
         */
        insertMenu("工作流管理", "历史工作流实例管理", menu_type_page, "historyProcessInstance", null);

        /**
         * 插入按钮
         * @param menuName      需要放置的菜单的名称
         * @param name          按钮的名称
         * @param url           按钮操作对应的后台url
         * @param privilegeCode 按钮权限code ,默认与admin角色关联
         */
        insertButton("历史工作流实例管理", "删除", "historyProcessInstance:delete", "/workflow/delete/history/process");

    }

}
